package com.edgegateway.web.controller.iot;

import com.alibaba.fastjson.JSON;
import com.edgegateway.common.annotation.Log;
import com.edgegateway.common.core.controller.BaseController;
import com.edgegateway.common.core.domain.AjaxResult;
import com.edgegateway.common.core.page.TableDataInfo;
import com.edgegateway.common.enums.BusinessType;
import com.edgegateway.common.pk.IdWorker;
import com.edgegateway.common.utils.StringUtils;
import com.edgegateway.common.utils.TelnetUtil;
import com.edgegateway.common.utils.poi.ExcelUtil;
import com.edgegateway.system.domain.IotEdgeGateway;
import com.edgegateway.system.domain.IotRuleFlow;
import com.edgegateway.system.service.IIotEdgeGatewayService;
import com.edgegateway.system.service.IIotRuleFlowService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 * 规则编排Controller
 * 
 * @author ruoyi
 * @date 2023-01-03
 */
@Api("边缘实例")
@Controller
@RequestMapping("/system/flow")
@Slf4j
public class IotRuleFlowController extends BaseController
{
    private String prefix = "iot/flow";

    @Autowired
    private IIotRuleFlowService iotRuleFlowService;

    @Autowired
    private IIotEdgeGatewayService iotEdgeGatewayService;

    @Autowired
    private IdWorker idWorker;

    @RequiresPermissions("system:flow:view")
    @GetMapping()
    public String flow()
    {
        return prefix + "/flow";
    }

    /**
     * 查询规则编排列表
     */
    @RequiresPermissions("system:flow:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(IotRuleFlow iotRuleFlow)
    {
        startPage();
        List<IotRuleFlow> list = iotRuleFlowService.selectIotRuleFlowList(iotRuleFlow);
        for (IotRuleFlow flow: list){
            IotEdgeGateway edgeGateway = iotEdgeGatewayService.selectIotEdgeGatewayById(flow.getEdgeGatewayId());
            boolean telnet = ckeckUrl(edgeGateway.getGatewayUrl());
            if(telnet && flow.getStatus() != 1){
                flow.setStatus(1);
                iotRuleFlowService.updateIotRuleFlow(flow);
            }
            if(!telnet && flow.getStatus() == 1) {
                flow.setStatus(0);
                iotRuleFlowService.updateIotRuleFlow(flow);
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出规则编排列表
     */
    @RequiresPermissions("system:flow:export")
    @Log(title = "规则编排", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(IotRuleFlow iotRuleFlow)
    {
        List<IotRuleFlow> list = iotRuleFlowService.selectIotRuleFlowList(iotRuleFlow);
        ExcelUtil<IotRuleFlow> util = new ExcelUtil<IotRuleFlow>(IotRuleFlow.class);
        return util.exportExcel(list, "规则编排数据");
    }

    /**
     * 新增规则编排
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存规则编排
     */
    @RequiresPermissions("system:flow:add")
    @Log(title = "规则编排", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(IotRuleFlow iotRuleFlow){
        ArrayList<Map> flows = new ArrayList<>();
        HashMap<String, Object> f = new HashMap<>();
        f.put("id",iotRuleFlow.getFlowId());
        f.put("type","tab");
        f.put("label",iotRuleFlow.getFlowName());
        f.put("disabled",false);
        f.put("info","");
        f.put("env",new ArrayList<>());
        flows.add(f);
        iotRuleFlow.setFlow(JSON.toJSONString(flows));
        iotRuleFlow.setId(idWorker.nextId());
        IotEdgeGateway gateway = iotEdgeGatewayService.selectIotEdgeGatewayById(iotRuleFlow.getEdgeGatewayId());
        boolean telnet = ckeckUrl(gateway.getGatewayUrl());
        if(telnet){
            iotRuleFlow.setStatus(1);
        }
        return toAjax(iotRuleFlowService.insertIotRuleFlow(iotRuleFlow));
    }

    /**
     * 修改规则编排
     */
    @RequiresPermissions("system:flow:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") String id, ModelMap mmap)
    {
        IotRuleFlow iotRuleFlow = iotRuleFlowService.selectIotRuleFlowById(id);
        mmap.put("iotRuleFlow", iotRuleFlow);
        return prefix + "/edit";
    }

    /**
     * 修改保存规则编排
     */
    @RequiresPermissions("system:flow:edit")
    @Log(title = "规则编排", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(IotRuleFlow iotRuleFlow)
    {
        return toAjax(iotRuleFlowService.updateIotRuleFlow(iotRuleFlow));
    }

    /**
     * 删除规则编排
     */
    @RequiresPermissions("system:flow:remove")
    @Log(title = "规则编排", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(iotRuleFlowService.deleteIotRuleFlowByIds(ids));
    }

    @GetMapping("/all")
    @ResponseBody
    public AjaxResult getAll(){
        List<IotRuleFlow> list = iotRuleFlowService.getAll();
        return AjaxResult.success(list);
    }

    /**
     * 判断地址是否可用
     * @param gatewayUrl
     * @return
     */
    public boolean telnet(String gatewayUrl){
        boolean b = false;
        if(StringUtils.isNotBlank(gatewayUrl)){
            try{
                URL url = new URL(gatewayUrl);
                String host = url.getHost();
                int port = url.getPort();
                if(port==-1){
                    port = url.getDefaultPort();
                }
                boolean telnet = TelnetUtil.telnet(host,port,200);
                if(telnet){
                    b=true;
                }
            }catch (MalformedURLException e){
                log.error("地址错误=>"+gatewayUrl);
            }
        }
        return b;
    }

    /**
     * 判断接口是否可用
     * @param gatewayUrl
     * @return
     */
    public boolean ckeckUrl(String gatewayUrl){
        boolean b = false;
        if(StringUtils.isNotBlank(gatewayUrl)){
            boolean telnet = TelnetUtil.checkUrl(gatewayUrl+"/diagnostics");
            if(telnet){
                b=true;
            }
        }
        return b;
    }

}
